import { onBeforeMount, onBeforeUnmount, computed, ref } from "vue";
import { eventBus } from "./eventBus";
import { useRouter } from "vue-router";

// curComp 调用useEvents的refs，curConfig配置信息
const useEvents = ({ curConfig }) => {
  const router = useRouter();
  //订阅事件
  onBeforeMount(() => {
    //所有监听的事件都会执行，这是一个全量的广播，放到这里和写到组件内部的区别是啥
    eventBus.on("compClick", compClick);

    eventBus.on("compFilter", compFilter);
    eventBus.on("compRouter", compRouter);
    eventBus.on("compDialog", compDialog);
  });
  onBeforeUnmount(() => {
    offEvent("compClick");
    offEvent("compFilter");
    offEvent("compRouter");
    offEvent("compDialog");
  });
  const showFilter = ref(true);
  const showCondition = computed(() => {
    return showFilter.value;
  });
  //eslint-disable-next-line
  const compClick = ({ emitConfig, emitParams }) => {};
  /**
   *
   * 用于处理各种筛选组件的逻辑：FilterMenu（点位筛选）、LayerFilter（图层筛选）、DepFilter（科室筛选）
   * 存在问题：
   *  FilterMenu与LayerFilter存在冲突，LayerFilter隐藏了所有点位后，再操作FilterMenu还是可以的，是否需要进行隐藏
   * 筛选逻辑：
   * 1.FilterMenu：
   *
   * 2.LayerFilter：layer_conduitup_display_block_none  layer_base_display_block_none
   * layer：筛选标识
   * conduitup：当前图层标识（wire、conduitup、conduitdown、base）其中base是底图
   * visibility：操作的style属性，分为start和end start就是匹配一致时执行、end是匹配不一致执行；如果没有stylename就直接执行显示隐藏
   *
   *3. DepFilter科室数据，要通知到根组件。其实是不是使用vina会好点
   */
  const compFilter = ({ emitConfig, emitParams }) => {
    let filterContion = curConfig.propValue.filter;
    if (curConfig.conditionFilter) {
      filterContion += ` ${curConfig.conditionFilter}`;
    }
    const compEmitData = emitParams["compEmitData"];
    const emitComponent = emitConfig.component;
    //自己不参与筛选自己
    if (emitComponent === curConfig.component) return;

    //组件FilterMenu的功能就是单纯的显示隐藏，这里由showCondition改为refs的样式控制
    if (emitComponent === "FilterMenu") {
      if (!compEmitData || !filterContion || filterContion?.indexOf(compEmitData) !== -1 || filterContion?.indexOf("filter_all") !== -1) {
        changeStyle("visibility", "visible");
      } else if (filterContion?.indexOf("menu") !== -1) {
        changeStyle("visibility", "hidden");
      }
    } else if (emitComponent === "PosFilter") {
      if (compEmitData) {
        if (!filterContion) return;
        if (typeof compEmitData === "object" && compEmitData.rawName) {
          if (filterContion?.indexOf(compEmitData.rawName) !== -1) {
            if (compEmitData.active) {
              changeStyle("visibility", "visible");
            } else {
              changeStyle("visibility", "hidden");
            }
          }
        }
      }
    } else if (emitComponent === "LayerFilter") {
      if (!compEmitData || !filterContion) {
        return;
      } else if (filterContion?.indexOf("layer") !== -1) {
        let layerContion = findUniqueMatch(filterContion, "layer");

        let splitStr = layerContion.split("_");
        const contion = `${splitStr[0]}_${splitStr[1]}`;
        const styleName = splitStr[2];
        const styleValStart = splitStr[3];
        const styleValEnd = splitStr[4];
        if (!styleName) {
          if (contion === compEmitData) {
            changeStyle("visibility", "visible");
          } else {
            changeStyle("visibility", "hidden");
          }
        } else {
          if (contion === compEmitData) {
            changeStyle(styleName, styleValStart);
          } else {
            changeStyle(styleName, styleValEnd);
          }
        }
      }
    } else if (emitComponent === "DepFilter") {
      if (!compEmitData || !filterContion || filterContion?.indexOf("dep_all") !== -1) {
        return;
      } else {
        // eventBus.emit("changeDep", { className: compEmitData });\
        if (filterContion?.indexOf(compEmitData) !== -1) {
          if (curConfig.component === "LayerFilter") {
            changeStyle("visibility", "visible");
            changeStyle("display", "block");
          } else {
            changeStyle("visibility", "visible");

            changeStyle("display", "block");
          }
        } else {
          if (filterContion?.indexOf("dep") !== -1) {
            if (curConfig.component === "LayerFilter") {
              changeStyle("visibility", "hidden");
              changeStyle("display", "none");

              eventBus.emit("layerAction", "layerBase");
              eventBus.emit("layerDepAction", "layerDepBase");

              // eventBus.emit("compFilter", { emitParams: { compEmitData: "layer_base" }, emitConfig: { component: "LayerFilter" } });
            } else {
              changeStyle("visibility", "hidden");

              changeStyle("display", "none");
            }
          }
        }
      }
    } else if (emitComponent === "layerSwitch") {
      // console.log(filterContion);
      if (!compEmitData || !filterContion) {
        return;
      } else if (filterContion?.indexOf("switch") !== -1) {
        if (compEmitData === "reset") {
          if (filterContion?.indexOf(compEmitData) !== -1) {
            changeStyle("visibility", "hidden");
            changeStyle("display", "none");
          }
          return;
        }
        // eventBus.emit("layerAction", "layerBase");
        eventBus.emit("layerDepAction", "onlyBtn");

        if (filterContion?.indexOf(compEmitData) !== -1) {
          changeStyle("visibility", "visible");
          changeStyle("display", "block");
        } else {
          changeStyle("visibility", "hidden");
          changeStyle("display", "none");
        }
      } else if (filterContion.indexOf("marking") !== -1 || curConfig.component === "ColorMarking") {
        changeStyle("display", "none");
      }
    } else if (emitComponent === "LayerDepFilter") {
      if (!compEmitData || !filterContion) {
        return;
      } else if (filterContion?.indexOf("layer_dep") !== -1) {
        let layerContion = findUniqueMatch(filterContion, "layer_dep");

        let splitStr = layerContion.split("_");
        let contion = `${splitStr[0]}_${splitStr[1]}_${splitStr[2]}`;
        const styleName = splitStr[3];
        const styleValStart = splitStr[4];
        const styleValEnd = splitStr[5];
        // if (splitStr[2] === "marking") {
        //   if (compEmitData !== "layer_dep_base") contion = compEmitData;
        // }
        if (!styleName) {
          if (contion === compEmitData) {
            if (contion !== "layer_dep_base") eventBus.emit("layerSwitch", "reset");
            else {
              eventBus.emit("layerSwitch", "front");
            }
            changeStyle("visibility", "visible");
          } else {
            changeStyle("visibility", "hidden");
          }
        } else {
          if (contion === compEmitData) {
            if (contion !== "layer_dep_base") eventBus.emit("layerSwitch", "reset");
            else {
              eventBus.emit("layerSwitch", "front");
            }

            changeStyle(styleName, styleValStart);
          } else {
            changeStyle(styleName, styleValEnd);
          }
        }
      }
    }
  };
  /**
   * 使用正则表达式查找源字符串中唯一包含查询字符串的单词。
   * @param {string} str - 源字符串，单词以空格分隔。
   * @param {string} findStr - 查询字符串，可以是完整或部分单词。
   * @returns {string} - 包含查询字符串的唯一单词，如果没有找到或不唯一，则返回空字符串。
   */
  function findUniqueMatch(str, findStr) {
    if (!str) return "";
    // 转义特殊字符以在正则表达式中使用
    const escapedFindStr = findStr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    // 修改正则表达式，以匹配包含查询字符串的单词，包括小数点
    const regex = new RegExp(`\\b\\w*${escapedFindStr}\\w*(\\.\\w+)?\\b`, "g");
    let matches = str.match(regex);

    // 确保匹配结果是唯一的
    if (matches && matches.length === 1) {
      return matches[0];
    }

    return "";
  }
  const compRouter = ({ emitConfig, emitParams }) => {
    if (emitConfig.id === curConfig.id) {
      const { compEmitData } = emitParams;
      let query = {};
      if (typeof compEmitData === "object") {
        query = { ...compEmitData };
      } else {
        query = {
          ...emitParams
        };
      }
      router.push({
        path: "/all/visual/template",
        query
      });
    }
    // console.log("compRouter", emitConfig, emitParams);
  };
  const compDialog = ({ emitConfig, emitParams }) => {
    console.log("compDialog", emitConfig, emitParams);
  };
  function offEvent(type) {
    switch (type) {
      case "compClick":
        eventBus.off("compClick", compClick);
        break;
      case "compFilter":
        eventBus.off("compFilter", compFilter);
        break;
      case "compRouter":
        eventBus.off("compRouter", compRouter);
        break;
      case "compDialog":
        eventBus.off("compDialog", compDialog);
        break;
      default:
        break;
    }
  }
  //根据名字判断是否为指定组件
  // function isFindComp(name) {
  //   return curConfig.component === name
  // }
  function changeStyle(styleName, value, compId = null) {
    // try {
    //   if (curComp.value) curComp.value.$el.style[styleName] = value;
    //   else {
    //     executeWithRetry(() => {
    //       curComp.value.$el.style[styleName] = value;
    //     }, curComp);
    //   }
    // } catch (e) {
    //   console.log(e);
    // }
    //由直接修改ref改为通知祖先组件修改props数据

    if (!compId && curConfig) compId = curConfig.id;
    eventBus.emit("changeStyle", { styleName, value, compId });
  }
  /**
   * 执行一个操作，如果$el为空，则在500ms后重试，可以指定重试的次数，默认为2次。
   * @param {Function} action - 要执行的操作，这是一个函数。
   * @param {Object} $el - 要检查的元素。
   * @param {number} [retryCount=2] - 重试的次数，默认为2次。
   */
  function executeWithRetry(action, curComp, retryCount = 2) {
    // 定义执行操作的函数
    const attemptAction = currentRetry => {
      if (curComp.value || currentRetry <= 0) {
        action();
      } else {
        // 如果$el为空且还有重试次数，设置定时器再次尝试
        setTimeout(() => {
          attemptAction(currentRetry - 1);
        }, 500);
      }
    };

    // 开始尝试执行操作
    attemptAction(retryCount);
  }

  return {
    offEvent,
    showCondition,
    executeWithRetry
  };
};
export default useEvents;
